{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# k-Nearest Neighbor\n",
    "\n",
    "\n",
    "This function illustrates how to use k-nearest neighbors in tensorflow\n",
    "\n",
    "We will use the 1970s Boston housing dataset which is available through the UCI ML data repository. \n",
    "\n",
    "### Data:\n",
    "----------x-values-----------\n",
    "* CRIM   : per capita crime rate by town\n",
    "* ZN     : prop. of res. land zones\n",
    "* INDUS  : prop. of non-retail business acres\n",
    "* CHAS   : Charles river dummy variable\n",
    "* NOX    : nitrix oxides concentration / 10 M\n",
    "* RM     : Avg. # of rooms per building\n",
    "* AGE    : prop. of buildings built prior to 1940\n",
    "* DIS    : Weighted distances to employment centers\n",
    "* RAD    : Index of radian highway access\n",
    "* TAX    : Full tax rate value per $10k\n",
    "* PTRATIO: Pupil/Teacher ratio by town\n",
    "* B      : 1000*(Bk-0.63)^2, Bk=prop. of blacks\n",
    "* LSTAT  : % lower status of pop\n",
    "\n",
    "------------y-value-----------\n",
    "* MEDV   : Median Value of homes in $1,000's"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# import required libraries\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import requests\n",
    "from tensorflow.python.framework import ops\n",
    "ops.reset_default_graph()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "sess = tf.Session()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "housing_url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data'\n",
    "housing_header = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']\n",
    "cols_used = ['CRIM', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'TAX', 'PTRATIO', 'B', 'LSTAT']\n",
    "num_features = len(cols_used)\n",
    "housing_file = requests.get(housing_url)\n",
    "housing_data = [[float(x) for x in y.split(' ') if len(x)>=1] for y in housing_file.text.split('\\n') if len(y)>=1]\n",
    "\n",
    "y_vals = np.transpose([np.array([y[13] for y in housing_data])])\n",
    "x_vals = np.array([[x for i,x in enumerate(y) if housing_header[i] in cols_used] for y in housing_data])\n",
    "\n",
    "## Min-Max Scaling\n",
    "x_vals = (x_vals - x_vals.min(0)) / x_vals.ptp(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Split the data into train and test sets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.random.seed(13)  #make results reproducible\n",
    "train_indices = np.random.choice(len(x_vals), round(len(x_vals)*0.8), replace=False)\n",
    "test_indices = np.array(list(set(range(len(x_vals))) - set(train_indices)))\n",
    "x_vals_train = x_vals[train_indices]\n",
    "x_vals_test = x_vals[test_indices]\n",
    "y_vals_train = y_vals[train_indices]\n",
    "y_vals_test = y_vals[test_indices]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parameters to control run"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Declare k-value and batch size\n",
    "k = 4\n",
    "batch_size=len(x_vals_test)\n",
    "\n",
    "# Placeholders\n",
    "x_data_train = tf.placeholder(shape=[None, num_features], dtype=tf.float32)\n",
    "x_data_test = tf.placeholder(shape=[None, num_features], dtype=tf.float32)\n",
    "y_target_train = tf.placeholder(shape=[None, 1], dtype=tf.float32)\n",
    "y_target_test = tf.placeholder(shape=[None, 1], dtype=tf.float32)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Declare distance metric"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### L1 Distance Metric\n",
    "\n",
    "Uncomment following line and comment L2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "distance = tf.reduce_sum(tf.abs(tf.subtract(x_data_train, tf.expand_dims(x_data_test,1))), axis=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### L2 Distance Metric\n",
    "\n",
    "Uncomment following line and comment L1 above"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#distance = tf.sqrt(tf.reduce_sum(tf.square(tf.subtract(x_data_train, tf.expand_dims(x_data_test,1))), reduction_indices=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Predict: Get min distance index (Nearest neighbor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Batch #1 MSE: 14.38\n"
     ]
    }
   ],
   "source": [
    "#prediction = tf.arg_min(distance, 0)\n",
    "top_k_xvals, top_k_indices = tf.nn.top_k(tf.negative(distance), k=k)\n",
    "x_sums = tf.expand_dims(tf.reduce_sum(top_k_xvals, 1),1)\n",
    "x_sums_repeated = tf.matmul(x_sums,tf.ones([1, k], tf.float32))\n",
    "x_val_weights = tf.expand_dims(tf.div(top_k_xvals,x_sums_repeated), 1)\n",
    "\n",
    "top_k_yvals = tf.gather(y_target_train, top_k_indices)\n",
    "prediction = tf.squeeze(tf.matmul(x_val_weights,top_k_yvals), axis=[1])\n",
    "#prediction = tf.reduce_mean(top_k_yvals, 1)\n",
    "\n",
    "# Calculate MSE\n",
    "mse = tf.div(tf.reduce_sum(tf.square(tf.subtract(prediction, y_target_test))), batch_size)\n",
    "\n",
    "# Calculate how many loops over training data\n",
    "num_loops = int(np.ceil(len(x_vals_test)/batch_size))\n",
    "\n",
    "for i in range(num_loops):\n",
    "    min_index = i*batch_size\n",
    "    max_index = min((i+1)*batch_size,len(x_vals_train))\n",
    "    x_batch = x_vals_test[min_index:max_index]\n",
    "    y_batch = y_vals_test[min_index:max_index]\n",
    "    predictions = sess.run(prediction, feed_dict={x_data_train: x_vals_train, x_data_test: x_batch,\n",
    "                                         y_target_train: y_vals_train, y_target_test: y_batch})\n",
    "    batch_mse = sess.run(mse, feed_dict={x_data_train: x_vals_train, x_data_test: x_batch,\n",
    "                                         y_target_train: y_vals_train, y_target_test: y_batch})\n",
    "\n",
    "    print('Batch #' + str(i+1) + ' MSE: ' + str(np.round(batch_mse,3)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nMW7cuCaXr1ixgl/96ldrE0H//v2rngTAVUNmlnO77bYbCxYsoK6ujiFDhnDUUUcxbNgwFi1axF13\n3cWYMWPYaaedOPTQQ1m1ahUAd9xxB0OHDmWnnXbixhs/GUxuypQpnHTSSQAsXbqUgw46iBEjRjBi\nxAgefvhhJk2axAsvvMDIkSM588wzqaurY9iwYUDWiH7MMccwfPhwRo0axYwZM9Zu8+CDD2bs2LEM\nHjyYs846q83LwInAzHJrzZo13H777QwfPhyA+fPnc8IJJzB37lx69erFhRdeyD333MMTTzxBbW0t\nl156Ke+99x7f/e53+dOf/sSsWbN47bXXGt32ySefzO67785TTz3FE088wQ477MBFF13ENttsw+zZ\ns/nZz362zvq//OUvkcScOXOYNm0aEyZMWHsn0OzZs7nuuuuYM2cO1113HYsWLWrTcnAiMLPcWb16\nNSNHjqS2tpaBAwdy7LHHArDVVlsxevRoAB555BGeeeYZdtllF0aOHMnUqVNZuHAhzz77LIMGDWLw\n4MFIYvz48Y3u49577+X447Phjbt06UKfPn0aXa/egw8+uHZbQ4cOZauttuL557Oq07322os+ffrQ\nvXt3tt9+exYuLKkvuZK5jcDMcqewjaBQr1691j6OCPbee2+mTZu2zjqNPa/cNtpoo7WPu3Tpwpo1\na9p0+74iMDNrxOjRo3nooYdYsGABAO+88w7PP/88Q4cOpa6ujhdeeAHgU4mi3l577cUVV1wBwEcf\nfcTKlSvp3bs3b7/9dqPr77bbblx99dUAPP/887z88ssMGTKkrQ+rUb4iMLOqaq93h/Xr148pU6Zw\n+OGH8/777wNw4YUXsu2223LllVey33770bNnT3bbbbdGT+6XX345EydOZPLkyXTp0oUrrriCMWPG\nsMsuuzBs2DC+/vWvc+KJJ65d/4QTTuD4449n+PDhdO3alSlTpqxzJVBOHWLM4tra2vDANJ2Tbx/N\nn3nz5rHddttVO4xOp7FylTQrImqbe66rhszMcs6JwMws55wIzMxyzonAzCznnAjMzHLOicDMLOf8\nOwIzq64ZP23b7e15Tkmr3XzzzRx00EHMmzePoUOHNrnelClT2Geffejfv3+rwinsprq9KtsVgaTf\nSVom6emCeZtKulvS/PR/k3Lt38ysmGnTprHrrrs2+cvgelOmTGHJkiUViqo6ylk1NAUY22DeJOAv\nETEY+EuaNjOrqFWrVvHggw8yefJkrr322rXzL774YoYPH86IESOYNGkS06dP5/HHH+eII45g5MiR\nrF69mpqaGt544w0AHn/8cfbYYw8AHnvsMcaMGcOoUaP40pe+xHPPPVeNQ2uVslUNRcT9kmoazD4A\n2CM9ngrcB5xdrhjMzBpzyy23MHbsWLbddlv69u3LrFmzWLZsGbfccguPPvooPXv25M0332TTTTfl\nF7/4BZdccgm1tcV/oDt06FAeeOABunbtyj333MO5557LDTfcUKEjWj+VbiPYPCJeTY9fAzav8P7N\nzJg2bRqnnHIKAIcddhjTpk0jIjjmmGPWDlm56aabtmibK1euZMKECcyfPx9JfPjhh20ed7lUrbE4\nIkJSkx0dSZoITAQYOHBgxeIys87tzTff5N5772XOnDlI4qOPPkIShx56aEnP79q1Kx9//DHA2oFj\nAM477zz23HNPbrrpJurq6tZWGXUElb59dKmkzwKk/8uaWjEiroyI2oio7devX8UCNLPObfr06Rx5\n5JEsXLiQuro6Fi1axKBBg+jTpw+///3veffdd4EsYQCf6jq6pqaGWbNmAaxT9bNy5Uq22GILIGtg\n7kgqfUVwKzABuCj9v6XC+zez9qbE2z3byrRp0zj77HWbJg855BDmzZvHuHHjqK2tZcMNN2Tffffl\nJz/5CUcffTTHHXccPXr0YObMmZx//vkce+yxnHfeeet86z/rrLOYMGECF154Ifvtt19Fj2l9la0b\naknTyBqGNwOWAucDNwPXAwOBhcC3IuLN5rblbqg7L3dDnT/uhro81qcb6nLeNXR4E4v2Ktc+zcys\n5dzFhJlZzjkRmFnFdYSRETuS9S1PJwIzq6ju3buzfPlyJ4M2EhEsX76c7t27t3ob7nTOzCpqwIAB\nLF68mNdff73aoXQa3bt3Z8CAAa1+vhOBmVVUt27dGDRoULXDsAKuGjIzyzknAjOznHMiMDPLOScC\nM7OccyIwM8s5JwIzs5xzIjAzyzknAjOznPMPyqxjmvHTppdVuH97s47OVwRmZjnnRGBmlnNOBGZm\nOedEYGaWc04EZmY550RgZpZzTgRmZjnnRGBmlnNOBGZmOedEYGaWc04EZmY550RgZpZzTgRmZjnn\nRGBmlnNOBGZmOVeVRCDpNElzJT0taZqk7tWIw8zMqpAIJG0BnAzURsQwoAtwWKXjMDOzTLWqhroC\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x107a73a90>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "# Plot prediction and actual distribution\n",
    "bins = np.linspace(5, 50, 45)\n",
    "\n",
    "plt.hist(predictions, bins, alpha=0.5, label='Prediction')\n",
    "plt.hist(y_batch, bins, alpha=0.5, label='Actual')\n",
    "plt.title('Histogram of Predicted and Actual Values')\n",
    "plt.xlabel('Med Home Value in $1,000s')\n",
    "plt.ylabel('Frequency')\n",
    "plt.legend(loc='upper right')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [conda env:tf-cpu]",
   "language": "python",
   "name": "conda-env-tf-cpu-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
